package com.swak.security;

import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.io.Serializable;

import com.alibaba.fastjson.util.TypeUtils;
import com.swak.Constants;

/**
 * 认证后的身份信息,只需要存储一个登录的用户ID
 *
 * @author: lifeng
 * @date: 2020/3/29 21:20
 */
public class Principal implements Externalizable {

	private static final long serialVersionUID = 1L;

	protected Serializable id;
	protected String name;
	private Serializable tenantId;
	private String tenantName;

	/**
	 * 目前在APP端使用：
	 * 
	 * type:appid:openid
	 */
	private String account;

	public Principal() {
	}

	public Principal(Serializable id) {
		this.id = id;
	}

	public Principal(Serializable id, String name) {
		this.id = id;
		this.name = name;
	}

	public Principal(Serializable id, String name, Serializable tenantId, String tenantName) {
		this.id = id;
		this.name = name;
		this.tenantId = tenantId;
		this.tenantName = tenantName;
	}

	public Principal(Serializable id, String name, Serializable tenantId, String tenantName, String account) {
		this.id = id;
		this.name = name;
		this.tenantId = tenantId;
		this.tenantName = tenantName;
		this.account = account;
	}

	public Serializable getId() {
		return id;
	}

	public String getIdAsString() {
		return TypeUtils.castToString(this.id);
	}

	public Long getIdAsLong() {
		return TypeUtils.castToLong(this.id);
	}

	public String getTenantIdAsString() {
		return TypeUtils.castToString(this.tenantId);
	}

	public Long getTenantIdAsLong() {
		return TypeUtils.castToLong(this.tenantId);
	}

	public void setId(Serializable id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Serializable getTenantId() {
		return tenantId;
	}

	public void setTenantId(Serializable tenantId) {
		this.tenantId = tenantId;
	}

	public String getTenantName() {
		return tenantName;
	}

	public void setTenantName(String tenantName) {
		this.tenantName = tenantName;
	}

	public String getAccount() {
		return account;
	}

	public void setAccount(String account) {
		this.account = account;
	}

	public boolean isRoot() {
		return this.id != null && this.getIdAsLong().equals(Constants.ADMIN);
	}

	public boolean isPlatform() {
		return this.tenantId != null && this.getTenantIdAsLong().equals(Constants.ROOT);
	}

	/**
	 * 将 tenant 伪装为 user, 目前只有 素材管理用到;
	 * 
	 * @return
	 */
	public Principal asUser() {
		return new Principal(tenantId, tenantName);
	}

	@Override
	public String toString() {
		if (this.tenantId != null) {
			return "Principal" + "@user=" + this.getId() + ",tenant=" + this.getTenantId();
		}
		return "Principal" + "@user=" + this.getId();
	}

	@Override
	public int hashCode() {
		if (this.tenantId != null) {
			return id.hashCode() + tenantId.hashCode();
		}
		return id.hashCode();
	}

	@Override
	public boolean equals(Object obj) {
		if (obj == null || !(obj instanceof Principal)) {
			return false;
		}

		Principal other = ((Principal) obj);
		return other.id.equals(this.id) && ((other.tenantId == null && this.tenantId == null)
				|| (other.tenantId != null && other.tenantId.equals(this.tenantId)));
	}

	@Override
	public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
		this.id = (Serializable) in.readObject();
		this.name = (String) in.readObject();
		this.tenantId = (Serializable) in.readObject();
		this.tenantName = (String) in.readObject();
		this.account = (String) in.readObject();
	}

	@Override
	public void writeExternal(ObjectOutput out) throws IOException {
		out.writeObject(this.id);
		out.writeObject(this.name);
		out.writeObject(this.tenantId);
		out.writeObject(this.tenantName);
		out.writeObject(this.account);
	}
}
